# encoding: utf-8

from pub.trans import TransBase, json2dict
from util.log import getLogger
logger = getLogger()

class RemoteFileTrans(TransBase):
    """ 文件传输协议
        向服务端发送文件：
        {
            "type": "Push File",
            "resourec": path_file,
            "target": path_file
        }
    """
    def __init__(self):
        super().__init__()

        self.dict_registers = {}  # UDP: "license": (ip, port)
                                  # TCP: "license": sock_proxy
        self.map_connection = {}  # UDP: (ip, port): (ip2, port2)
                                  # TCP: sock_proxy: sock_proxy2

    ###########################################################################
    def reply(self, msg: bytes, sock1addr=None):
        # logger.debug("接收到消息：【{}】".format(msg))
        msg_head, msg_body = self.sock.msg_split(msg)

        if self.check_cmd(msg):
            dict_msg = json2dict(msg_body)
            if dict_msg["type"] == "Push File":
                self.reply_push_file(dict_msg, sock1addr)
            elif dict_msg["type"] == "Pull File":
                self.reply_pull_file(dict_msg, sock1addr)
            else:
                err = "Unkown command [{}]".format(msg)
                self.send_error(err.encode(), sock1addr)

        elif self.check_data(msg):
            # logger.debug("转发数据【{}】".format(msg))
            self.save_file(msg_body, sock1addr)

        else:
            err = "Unkown request [{}]".format(msg)
            self.send_error(err.encode(), sock1addr)

    def parse_reply(self, msg: bytes):
        # logger.debug("接收到回复：【{}】".format(msg))
        msg_head, msg_body = self.sock.msg_split(msg)

        if self.check_cmd(msg):
            dict_msg = json2dict(msg_body)
            if dict_msg["type"] == "Push File":
                self.on_push_file(dict_msg)
            elif dict_msg["type"] == "Pull File":
                self.on_pull_file(dict_msg)
            else:
                print("未解析命令【{}】".format(msg))

        elif self.check_data(msg):
            # logger.debug("接收到数据【{}】".format(msg_body))
            self.save_file(msg_body, self.sock)

        else:
            logger.error("Fail to parse the message【{}】.".format(msg))

    def push_file(self, path_from, path_to):
        dict_msg = {
            "type": "Push File",
            "source": path_from,  # 本地文件路径
            "target": path_to
        }
        self.send_cmd(dict_msg)

    def reply_push_file(self, dict_msg, sock1addr):
        self.send_cmd(dict_msg, sock1addr)
        # 本地暂存状态信息【source、target】
        sock1addr.path_save = dict_msg["target"]

    def on_push_file(self, dict_msg):
        with open(dict_msg["source"], "rb") as fp:
            file_data = fp.read()
        self.send_data(file_data)

    def pull_file(self, path_from, path_to):
        dict_msg = {
            "type": "Pull File",
            "source": path_from,  # 远程文件路径
            "target": path_to
        }
        self.send_cmd(dict_msg)

    def reply_pull_file(self, dict_msg, sock1addr):
        self.send_cmd(dict_msg, sock1addr)
        # 本地暂存状态信息【source、target】
        # sock1addr.path_pull_from = dict_msg["source"]
        with open(dict_msg["source"], "rb") as fp:
            file_data = fp.read()
        self.send_data(file_data, sock1addr)

    def on_pull_file(self, dict_msg):
        self.sock.path_save = dict_msg["target"]

    def save_file(self, data, sock1addr=None):
        with open(sock1addr.path_save, "wb") as fp:
            fp.write(data)

        logger.debug("接收到文件，存储于【{}】".format(sock1addr.path_save))
        del sock1addr.path_save
